#include "stdafx.h"
#include "ASN1Sequence.h"
#include "ASN1Null.h"
#include "ASN1Integer.h"

TEST(ASN1Sequencetest, GetInstance)
{
	AppliedCryptography::ASN1Sequence seq;
	AppliedCryptography::ASN1Sequence seqInst;
	AppliedCryptography::ASN1Integer oInt1(-129), oInt2(30);
	AppliedCryptography::ASN1Integer oIntInst;
	AppliedCryptography::ASN1Encodable *obj;

	seq.add(oInt1);
	seq.add(oInt2);

	obj = &seq;

	EXPECT_NO_THROW(seqInst = AppliedCryptography::ASN1Sequence::getInstance(*obj));

	EXPECT_EQ(2, seqInst.size());
	EXPECT_NO_THROW(oIntInst = AppliedCryptography::ASN1Integer::getInstance(seqInst.get(0)) );
	EXPECT_EQ(-129, oIntInst.get());
	EXPECT_NO_THROW(oIntInst = AppliedCryptography::ASN1Integer::getInstance(seqInst.get(1)) );
	EXPECT_EQ(30, oIntInst.get());
};

TEST(ASN1SeqEncodingTest, Encode)
{
	AppliedCryptography::ASN1Sequence seq;
	byte expBytes[] = {0x30, 0x02, 0x05, 0x00};
	std::vector<byte> expected(expBytes, expBytes + sizeof(expBytes) / sizeof(byte));
	std::vector<byte> ret;

	AppliedCryptography::ASN1Null oNull;
	AppliedCryptography::ASN1Integer oInt(-129);

	seq.add(oNull);

	ret = seq.encode();

	// Output size should be as expected
	ASSERT_EQ(expected.size(), ret.size());

	for(unsigned int i = 0; i < expected.size(); ++i)
	{
		EXPECT_NO_THROW(EXPECT_EQ((int)expected.at(i), (int)ret.at(i)) 
			<< "Index i: " << i);
	};

	seq.add(oInt);
	byte expBytesExtend[] = {0x02, 0x02, 0xFF, 0x7F};
	expected.insert(expected.end(), expBytesExtend, expBytesExtend + sizeof(expBytesExtend) / sizeof(byte));
	expected[1] += 4;

	ret = seq.encode();

	// Output size should be as expected
	ASSERT_EQ(expected.size(), ret.size());

	for(unsigned int i = 0; i < expected.size(); ++i)
	{
		EXPECT_NO_THROW(EXPECT_EQ((int)expected.at(i), (int)ret.at(i)) 
			<< "Index i: " << i);
	};
};
